#ifndef BUFFERFILLHELPER_H
#define BUFFERFILLHELPER_H

#pragma once

#include "../ToolkitLayer.h"
#include <IBuffer/IBuffer.h>

#if defined (__APPLE__)
	#define __stdcall
#endif


/**
 * This class provides types and methods that help filling a buffer. It
 * includes methods that fill a buffer using multithreading (based on the
 * multithreading used in the original version of the framework by T. Isenberg
 * and A. Miede).
 *
 * @author Fabricio Anastacio - fabriciocfa@yahoo.com
 * @since October 11, 2007
 */
class TOOLKITLAYER_API BufferFillingHelper
{
	// Types
public:
	/** The data of a quad to filled by the multithread target function. */
	typedef struct {
		/** The reference to the buffer to be filled. */
		IBuffer<float>* buffer;
		/** The type of filling to be used for this quad. */
		int fillType;
		/** The x-coordinate for point 0. */
		int x0;
		/** The y-coordinate for point 0. */
		int y0;
		/** The value for point 0. */
		float v0[2];
		/** The x-coordinate for point 1. */
		int x1;
		/** The y-coordinate for point 1. */
		int y1;
		/** The value for point 1. */
		float v1[2];
		/** The x-coordinate for point 2. */
		int x2;
		/** The y-coordinate for point 2. */
		int y2;
		/** The value for point 2. */
		float v2[2];
		/** The x-coordinate for point 3. */
		int x3;
		/** The y-coordinate for point 3. */
		int y3;
		/** The value for point 3. */
		float v3[2];
	} Quad2f;

	/** A collection of quad data to be passed to the multithread target function. */
	typedef struct {
		/** The number of quads in the data array. */
		int nQuads;
		/** The array with quad data. */
		Quad2f *quadData;
	} ArrayQuad2f;

	// Attributes
private:

	// Methods
public:
	/**
	 * Constructs a buffer filling helper.
	 */
	BufferFillingHelper(void);
	/**
	 * Destroys this buffer filling object.
	 */
	~BufferFillingHelper(void);

	/**
	 * Fills the buffer segments with an array of quads passed as parameter.
	 * It is meant to be called in a separate thread.
	 *
	 * @param params the array of quads to be filled.
	 */
	static unsigned int __stdcall fillBufferSegments(void* params);


	/**
	 * Utility wrapper method which calls fillBufferSegments(void*), except the returned variable is discarded.
	 * This method was created for use with pthreads.
	 *
	 * @param params the array of quads to be filled.
	 */
	static void* fillBufferSegmentsVoid(void* params);


	/**
	 * Fills a buffer with the values given by the array of quads using
	 * multithreading.
	 *
	 * @param quads the array of quads to be filled.
	 * @param numThreads the number of threads to be created.
	 * @param offset the offset in the quads array for the data to be used for
	 * each thread.
	 * @param nQuadsAdjustment the adjustment done to the number of quads for
	 * the last thread.
	 */
	static void multithreadFill(Quad2f* quads, unsigned int numThreads,
		unsigned int offset, unsigned int nQuadsAdjustment);
};

#endif  // BUFFERFILLHELPER_H
